<template>
    <div>
        <!-- “:inline="true"”表示“一行显示表单”（即“行内表单”） -->
        <el-form ref="searchForm" :model="searchMap" :inline="true" class="demo-form-inline">
            <el-form-item prop="name">
                <el-input v-model="searchMap.name" class="name" placeholder="             姓名             "></el-input>
            </el-form-item>
            <el-form-item prop="phoneNumber">
                <el-input v-model="searchMap.phoneNumber" class="phoneNumber" placeholder="       电话号码       "></el-input>
            </el-form-item>
            <el-form-item prop="brandAndModel">
                <el-select v-model="searchMap.brandAndModel" class="brandAndModel" placeholder="手机的品牌和型号">
                    <el-option v-for="option in brandAndModelOptions" :key="option.id" :label="option.name" :value="option.id"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item prop="payType" v-if="!isDialog">
                <el-select v-model="searchMap.payType" class="payType" placeholder="    支付方式    ">
                    <!-- 在此处不要忘记把全局变量“payTypeOptions”绑定到“data()”中，否则浏览器会报错说“payTypeOptions未定义”（也就是说在模板中引用不了全局变量。因为浏览器只会从Vue实例中的data属性中去找这个变量。所以如果不把它绑定到“data()”里，浏览器就找不到它）↓ -->
                    <el-option v-for="option in payTypeOptions" :key="option.type" :label="option.name" :value="option.type"></el-option>
                </el-select>
            </el-form-item>
            <el-form-item prop="purchaseDate" v-if="!isDialog">
                <!-- “value-format”被用作指定绑定值（即“日期”）的格式↓ -->
                <el-date-picker value-format="yyyy-MM-dd" v-model="searchMap.purchaseDate" type="date" class="purchaseDate" placeholder="            购机日期            "></el-date-picker>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" @click="fetchData">查询</el-button>
                <el-button type="primary" @click="handleAdd" v-if="!isDialog">新增</el-button>
                <el-button @click="resetForm('searchForm')" v-if="!isDialog">重置</el-button>
            </el-form-item>
        </el-form>
        <!-- 这是数据列表↓；“:data”表示“绑定渲染的数据”；“border”表示“这个表格带边框”；“:cell-style="rowStyle"”表示“该表格的内容文字居中对齐”（因为我已在下面“script”标签内导出的默认对象中的“methods”（方法）中定义了“rowStyle(){}”的函数体为“return "text-align:center"”）；“align="center"”表示“该表格的表头文字居中对齐”-->
        <!-- “type="index"”表示“获取从1开始的索引值”；“label”表示“显示的标题”；“prop”表示“数据字段名” -->
        <!-- <el-table :data="list" :cell-style="rowStyle" height="380" border style="width: 100%"> -->
        <!-- 1.“highlight-current-row”被用于激活单选行；2.当点击某一行后会触发事件“@current-change”，从而调用对应的函数“clickCurrentRow2”，并且这个函数会接收两个参数：“currentRow”（当前行）和“oldCurrentRow”（旧的行）（其中“oldCurrentRow”可以不填（即不传入），因为用得较少）↓ -->
        <!-- “ :highlight-current-row="isDialog"”表示“只有当‘Supplier’作为‘Goods’的子组件是被弹出的对话框而非普通的表格时，‘选中并高亮显示当前行’才有效”↓ -->
        <el-table ref="table" :data="list" :cell-style="rowStyle" height="380" border style="width: 100%" :highlight-current-row="isDialog" @current-change="clickCurrentRow2">
            <el-table-column type="index" align="center" width="50" label="序号"></el-table-column>
            <el-table-column prop="name" width="70" align="center" label="姓名"></el-table-column>
            <el-table-column prop="phoneNumber" width="120" align="center" label="手机号码"></el-table-column>
            <el-table-column prop="brandAndModel" :width="brandAndModelStyle" align="center" label="手机的品牌和型号"><!-- “"scope"”代表“当前行对象” --><template slot-scope="scope"><span>{{scope.row.brandAndModel | brandAndModelfilter}}</span></template></el-table-column>
            <!-- “:src="url"”表示“缩略图的路径”；“:preview-src-list="[url]"”表示被放大预览的图片的实际路径。在此处，缩略图和被放大预览的图片是同一张图（因为它们的路径都是"url"）↓ -->
            <el-table-column align="center" width ="50" label="外观" v-if="!isDialog"><!-- 图片查看器（兼容IE浏览器）→ --><a style="cursor: pointer;" @click="onPreview">预览</a><el-image ref="preview" class="hideImgDiv" :src="url" :preview-src-list="[url]" :z-index="9999"></el-image></el-table-column>
            <el-table-column prop="purchaseDate" width="100" align="center" label="购机日期" v-if="!isDialog"></el-table-column>
            <el-table-column prop="price" width="55" align="center" label="价格" v-if="!isDialog"></el-table-column>
            <el-table-column prop="integral" width="55" align="center" label="积分" v-if="!isDialog"></el-table-column>
            <el-table-column prop="payType" width="95" align="center" label="支付方式" v-if="!isDialog"><template slot-scope="scope"><span><!-- 这个数据绑定表示把当前行内“支付方式”列里面的数据作为参数传入到名为“payTypefilter”的过滤器中→ -->{{scope.row.payType | payTypefilter}}</span></template></el-table-column>
            <el-table-column prop="address" align="center" label="地址" v-if="!isDialog"></el-table-column>
            <el-table-column width="145" align="center" label="操作" v-if="!isDialog"><template slot-scope="scope"><el-button size="mini" @click="handleEdit(scope.row.id)">编辑</el-button><el-button size="mini" type="danger" @click="handleDelete(scope.row.id)">删除</el-button></template></el-table-column>
        </el-table>
        <!-- 分页组件 -->
        <!-- 此处不能使用@size-change="fetchData"和@current-change="fetchData"，否则“当前页码”和“每页显示的数据条数”只能是初始值（因为未传入新值）↓ -->
        <!-- <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes="[10, 20, 30, 40]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total"> </el-pagination> -->
        <!-- layout="total, sizes, prev, pager, next, jumper"↓ --><!-- Customer若是普通的表格，则分页组件显示完整版；Customer若是对话框，则分页组件只显示“页码”、“上一页”和“下一页”↓ -->
        <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes="[10, 20, 30, 40]" :page-size="pageSize" :layout="!isDialog ? 'total, sizes, prev, pager, next, jumper':'prev, pager, next'" :total="total"> </el-pagination>

        <!-- 这是新增客户用的对话框。其中“title”表示“对话框的标题”，当“:visible.sync”为“true”时会弹出对话框↓ -->
        <el-dialog title="编辑客户" :visible.sync="dialogFormVisible" width="376.5px">
            <el-form :model="beSubmittedData" ref="beSubmittedForm" :rules="rules" label-width="125px" label-position="right" style="width:356.5px;">
                <el-form-item label="客户姓名" prop="name"> <!-- “autocomplete”是HTML5中新出的属性，被用作“浏览器自动填充用户在输入框中曾经输入过的数据”↓ -->                    
                    <el-input v-model="beSubmittedData.name" style="width: 160px;" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="手机号码" prop="phoneNumber">
                    <el-input v-model="beSubmittedData.phoneNumber" style="width: 160px;" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item prop="brandAndModel" label="品牌型号">
                    <el-select v-model="beSubmittedData.brandAndModel" style="width: 160px;" placeholder="手机的品牌和型号">
                        <el-option v-for="option in brandAndModelOptions" :key="option.id" :label="option.name" :value="option.id"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item prop="purchaseDate" label="购机日期">
                    <el-date-picker value-format="yyyy-MM-dd" v-model="beSubmittedData.purchaseDate" type="date" style="width: 160px;" placeholder="      购机日期      "></el-date-picker>
                </el-form-item>
                <el-form-item label="购机价格" prop="price">
                    <el-input v-model="beSubmittedData.price" style="width: 160px;" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item label="现有积分" prop="integral">
                    <el-input v-model="beSubmittedData.integral" style="width: 160px;" autocomplete="off"></el-input>
                </el-form-item>
                <el-form-item prop="payType" label="支付方式">
                    <el-select v-model="beSubmittedData.payType" style="width: 160px;" placeholder="          支付方式          ">
                        <el-option v-for="option in payTypeOptions" :key="option.type" :label="option.name" :value="option.type"></el-option>
                    </el-select>
                </el-form-item>
                <el-form-item label="客户地址" prop="address">
                    <el-input type="textarea" v-model="beSubmittedData.address" style="width: 160px;" autocomplete="off"></el-input>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <!-- <el-button type="primary" @click="addData('beSubmittedForm')">确 定</el-button> -->
                <el-button type="primary" @click="beSubmittedData.id === null ? addData('beSubmittedForm') : updateData('beSubmittedForm')">确 定</el-button>
                <el-button @click="dialogFormVisible = false">取 消</el-button>
            </div>
        </el-dialog>

    </div>
</template>

<script>
import customerApi from '@/api/customer'

var fileName = 'HUAWEI Mate30 5G'

// 支付类型
const payTypeOptions = [
    {type:'1',name:'支付宝'},
    {type:'2',name:'微信'},
    {type:'3',name:'现金'},
    {type:'4',name:'POS机刷卡'}
]
const brandAndModelOptions = [
    {id:'1',name:'华为 Mate30 5G'},
    {id:'2',name:'小米 MIX4'},
    {id:'3',name:'OPPO reno6 5G'},
    {id:'4',name:'vivo X70'},
]

export default {
    props:{
        // 接收父组件Staff传递过来的数据，通过“isDialog”来判断是否为弹出的对话框。当“isDialog”的值为“true”时是弹出的对话框，为“false”时则是普通的列表（表格）。
        isDialog:Boolean
    },
    name: 'Index',
    data() {
        return {
            // url:'https://cube.elemecdn.com/6/94/4d3ea53c084bad6931a56d5158a48jpeg.jpeg',
            // 以文件名作为变量，在文件名的前面拼接这些图片文件的所在路径，在文件名的后面拼接这些图片文件的后缀名“.jpg”，以生成该目录下不同图片文件的完整路径，并用require()将这些图片导入，供“:preview-src-list="[url]"”动态加载
            url:require('/src/assets/' + fileName + '.jpg'),
            
            list:[],

            total:0, // ←左边这项表示“总记录数”
            currentPage:1, // ←左边这项表示“当前页码”
            pageSize:10, // ←左边这项表示“每页显示10条数据”
            searchMap:{ // ←左边这项表示“条件查询绑定的条件值（字段值）”
                // 在“searchMap”中明确指定需要的属性名（字段名），以防止输入时被卡死↓
                name:'',
                phoneNumber:'',
                brandAndModel:'',
                payType:'',
                purchaseDate:''
            },
            payTypeOptions, // ←左边这项相当于“payTypeOptions:payTypeOptions”，表示把全局变量“payTypeOptions"绑定进来
            
            // 这个名为“payTypeOptions”的数组不能被放在此处↓，只能被放在上面↑“export default{}”的外面（即定义为全局变量），否则会报错。原因见下方↓“需要注意的一个特性”
            /* payTypeOptions:[
            {type:'1',name:'支付宝'},
            {type:'2',name:'微信'},
            {type:'3',name:'现金'},
            {type:'4',name:'POS机刷卡'}
            ] */

            brandAndModelOptions,
            dialogFormVisible:false, // ←左边这项被用来控制对话框是否会被弹出
            beSubmittedData:{ // ←左边这项被用来表示“在对话框中被提交的数据”
                id:null,
                name:"",
                phoneNumber:"",
                brandAndModel:"",
                purchaseDate:"",
                price:"",
                integral:"",
                payType:"",
                address:""
            }, 
            rules:{ // ←左边这项被用来表示“表单的校验规则”
                name:[{required:true,message:'客户姓名不能为空',trigger:'blur'}],
                phoneNumber:[{required:true,message:'手机号码不能为空',trigger:'blur'},{min:11,max:11,message:'手机号码是11位数',trigger:'blur'}],
                brandAndModel:[{required:true,message:'品牌型号不能为空',trigger:'change'}],
                purchaseDate:[{required:true,message:'购机日期不能为空',trigger:'blur'}],
                price:[{required:true,message:'购机价格不能为空',trigger:'blur'}],
                integral:[{required:true,message:'现有积分不能为空',trigger:'blur'}],
                payType:[{required:true,message:'支付方式不能为空',trigger:'change'}],
                address:[{required:true,message:'客户地址不能为空',trigger:'blur'}],
            },
        }
    },
    created() {
        // 初始化获取列表数据
        this.fetchData()
    },
    
    methods: { 
        // 这个函数（方法）在“每页显示条数被改变”时被触发，“value”代表“最新的每页显示的条数”↓
        handleSizeChange(value){
            console.log(value)
            this.pageSize = value
            this.fetchData()
        },
        // 这个函数（方法）在“当前页码被改变”时被触发，“value”代表“最新的页码”↓
        handleCurrentChange(value){
            console.log(value)
            this.currentPage = value
            this.fetchData()
        },
        // 重置行内表单
        resetForm(formName){
            console.log('重置行内表单',formName)
            // 重置要看“el-form-item”这个组件元素的“prop”属性上是否指定了字段名，只有指定了字段名，重置才会生效。
            this.$refs[formName].resetFields();
        },
        fetchData(){
            /* customerApi.getList().then(response => {
                const be_responsed_customer_data = response.data
                this.list = be_responsed_customer_data.data
                console.log(be_responsed_customer_data)
            }) */
            customerApi.search(this.currentPage,this.pageSize,this.searchMap).then(response => {
                // 调用分页查询数据
                const be_responsed_customer_data = response.data
                console.log(be_responsed_customer_data.data.rows)
                console.log(be_responsed_customer_data.data.total)
                this.list = be_responsed_customer_data.data.rows
                this.total = be_responsed_customer_data.data.total
            })
        },
        // 打开编辑窗口
        handleEdit(id){
            console.log('编辑',id)
            this.handleAdd() // ←注意：此处不能直接使用“this.dialogFormVisible = true”来弹出对话框，因为需要调用“handleAdd”方法来清除这个对话框在这次被打开之前被打开时里面的表单上面可能残存的数据和样式（即校验结果）
            customerApi.getCustomerInformationById(id).then(response => {
                const be_responsed_data = response.data
                if (be_responsed_data.flag) {
                    this.beSubmittedData = be_responsed_data.data
                    console.log(this.beSubmittedData)
                }
                else{ //提示获取数据失败
                    this.$message({
                        message:be_responsed_data.message,
                        type:'warning',
                        center:true
                    })
                }
            })
        },
        // 删除客户
        handleDelete(id){
            console.log('删除',id)
            this.$confirm('你确定要删除这位客户吗？','提示',{
                confirmButtonText:'确定',
                cancelButtonText:'取消'
            }).then(() => {
                // 若点击“确定”则执行如下代码↓
                console.log('确认')
                customerApi.deleteCustomerInformationById(id).then(response => {
                    const be_responsed_data = response.data
                    this.$message({
                        message:be_responsed_data.message,
                        center:true,
                        type:be_responsed_data.flag?'success':'error'
                    })
                    if (be_responsed_data.flag) {
                        // 删除客户成功，然后刷新列表数据
                            this.fetchData()
                    }
                })
            }).catch(() =>{
                // 点击“取消”。此处无需做任何逻辑处理（因为浏览器会自动关闭消息提示框）
                console.log('取消')
            })
        },
        // 提交新增的数据
        addData(formName){
            this.$refs[formName].validate(valid => {
                if(valid){
                    // 提交表单
                    console.log('addData')
                    customerApi.addCustomer(this.beSubmittedData).then(response => {
                        const be_responsed_data = response.data
                        if(be_responsed_data.flag){
                            // 新增客户成功，然后刷新列表数据
                            this.fetchData()
                            this.dialogFormVisible = false // 关闭窗口
                        }
                        else{
                            // 新增客户失败，弹出提示信息
                            this.$message({
                                message:be_responsed_data.message,
                                type:'warning',
                                center:true
                            })
                        }
                    })
                }
                else{
                    return false
                }
            })
        },
        // 更新数据
        updateData(formName){
            console.log('updateData')
            this.$refs[formName].validate(valid => {
                if (valid) {
                    // 提交更新的数据
                    customerApi.updateCustomerInformation(this.beSubmittedData).then(response =>{
                        const be_responsed_data = response.data
                        if (be_responsed_data.flag) {
                            // 更新数据成功，然后刷新数据列表
                            this.fetchData()
                            this.dialogFormVisible = false
                        }
                        else{
                            this.$message({
                                message:be_responsed_data.message,
                                type:'warning',
                                center:true
                            })
                        }
                    })
                }
                else{
                    return false
                }
            })
        },
        // 弹出新增窗口
        handleAdd(){
            console.log(this.beSubmittedData)
            // this.beSubmittedData = {}
            this.dialogFormVisible = true
            this.$nextTick(() => { // ←左边这项是Vue中提供的内置的方法，因为回调函数无参数，所以要保留小括号。另外“this.$nextTick”是一个“异步事件”（指“当页面渲染结束后它的回调函数才会被执行”的事件），因为弹出窗口打开后需要花费时间加载（渲染）Dom（即那个表单），所以我们就应该等待它加载完成后再调用“resetFields”方法来重置表单和清除样式。
                this.$refs['beSubmittedForm'].resetFields()
            })
        },
        // 当点击表格中的某一行时，会调用这个函数进行处理
        clickCurrentRow2(currentRow){
            this.$message({
                message:'提示：当前选择的客户的姓名是' + currentRow.name + '，' + '手机号码是' + currentRow.phoneNumber + '，' + '客户购买的手机的品牌和型号是' + currentRow.brandAndModelOfCellphone + '，' + '购买时的价格是' + currentRow.price +'。',
                // type:'success'
            })
            console.log(currentRow.name)
            console.log(currentRow.phoneNumber)
            console.log(currentRow.brandAndModelOfCellphone)
            console.log(currentRow.price)
            console.log(`提示：当前选择的客户的姓名是${currentRow.name}，手机号码是${currentRow.phoneNumber}，客户购买的手机的品牌和型号是${currentRow.brandAndModelOfCellphone}，购买时的价格是${currentRow.price}。`)
            // this.$emit(event, ${[…args]})，其中第一个参数“event”表示“被触发的事件的名称”（注意：一定要用英文状态下的单引号把该事件的名称引起来，否则浏览器的控制台会报错说“该事件未定义”），第二个参数“${[…args]}”表示“被传递的数据”↓
            // 点击后，若要将点击的数据传递到父组件“Staff”（员工管理）中，则可以触发父组件“Staff”中的自定义事件“be_Selected_Customer”（因为这个事件被触发后父组件“Staff”可以在这个事件对应的处理函数中接收到数据“currentRow”）↓
            this.$emit('be_Selected_Customer', currentRow)
        },
        rowStyle(){
            return "text-align:center";
        },
        brandAndModelStyle(){
            if (!isDialog) {
                return "135";
            } else {
                return "auto";
            }
        },
        onPreview(BrandandModel) {
          //调用image组件中的大图浏览图片方法
          this.$refs.preview.clickHandler();
        },
    },

    filters: {
        payTypefilter(type){
            /* payTypeOptions.find(obj =>{
                return obj.type === type
            }) */
            // 如果return后面跟的是一个表达式，且这个返回值只有1个，则可把上面↑这段文字简写如下↓
            // 需要注意的一个特性：因为在过滤器中不能引用当前实例（即不能使用“this”关键字），所以“this.payTypeOptions”这个写法是错误的
            const payObject = payTypeOptions.find(obj => obj.type === type)
            return payObject ? payObject.name : null
        },
        brandAndModelfilter(id){
            const brandAndModelObject = brandAndModelOptions.find(obj => obj.id === id)
            return brandAndModelObject ? brandAndModelObject.name : null
        }
    },

    watch: {
        // 监听器（监听表格绑定的数据发生的变化。被用于当表格绑定的数据发生变化时重新布局表格，使每一列的表头与表体不发生错位）
        list:{
            handler(){
                this.$nextTick(() => {
 		            // 初始化表格（即每一列在接收到新数据时根据新的数据自动重新调整列宽（即“重新布局表格”），使表头与表体不发生错位）
                    this.$refs.table.doLayout();
                })
            },
            deep:true
        }
    }
}
</script>

<style lang="scss" scoped>
    /*1.此处使用“scss”规则来隐藏el-image图片组件中不需要展示的的img标签（即图片的缩略图）；2.“::v-deep”操作符表示“深度作用”↓*/
    .hideImgDiv{::v-deep.el-image__inner{display: none;}}
    .el-pagination{text-align: center;}
    .el-form{
        margin-top:15px;
        margin-bottom:15px;
        height:40px;
    }
    .payType{width: 118px;}
    .purchaseDate{width: 210px;}
    .brandAndModel{width: 160px;}
    .name{width: 160px;}
    .phoneNumber{width: 140px;}
    .el-select-dropdown__item{text-align: center;}
    // div{::v-deep.el-dialog{width: 376.5px;}}
    div{::v-deep.el-dialog__body{height: 350px;overflow-y: auto;overflow-x: hidden;}}
    div{::v-deep.el-form-item__error{white-space: pre;top: 28px;}}
    div{::v-deep.el-textarea__inner{height: 38px;text-align: center;}}
    div{::v-deep.el-input__inner{text-align: center;}}
    div{::v-deep.el-pagination{margin-top: 5px;margin-bottom: 5px;}}
</style>